fix(apple-watch): Apple Health shows inflated distance for treadmill workouts (km written as miles) - #4798
Merged
Merged
Conversation
…hKit Il canale iPhone→Watch via WatchConnectivity trasportava un valore con unità inconsistente: miglia quando l'iPhone era il device primario (lockscreen::setDistance convertiva km→mi), km quando un altro device QZ (iPad, "SENDER=PAD") inviava la distanza grezza. Il Watch scriveva sempre il valore ricevuto come HKUnit.mile(), causando distanze gonfiate in Apple Health (4.4 mi invece di 2.78 mi per 4.47 km). Fix: standardizzare il contratto a "sempre km" su quel canale. - lockscreen.mm: rimuove la conversione * 0.621371, invia km grezzi - WatchWorkoutTracking stopWorkOut(): moltiplica per 0.621371 prima di scrivere su HealthKit, così il Watch fa sempre la conversione finale Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Owner
Author
|
mail from |
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Root cause
When a workout ends, the Apple Watch writes the total distance to HealthKit via
WatchWorkoutTracking.stopWorkOut(). The value it writes comes fromWorkoutTracking.distance, which is populated fromWatchKitConnection.distance(Watch side) on every heart-rate tick.WatchKitConnection.distance(Watch side) is set from the WatchConnectivity reply that the iPhone sends back whenever the Watch pings it.The bug is a unit mismatch in that reply value. Depending on which device is the QZ primary:
WatchKitConnection.distance(iPhone) is setlockscreen::setDistance(km)→km * 0.621371→ storedSENDER=PAD)Connection.swiftreads rawODO=from local-network messageThe Watch always wrote the received value with
HKUnit.mile(), so in the iPad-primary scenario it was writing km as if they were miles. A 4.47 km run showed up as 4.47 mi in Apple Health instead of 2.78 mi.Evidence from the debug log
The log for the reported session (
iFIT_Xenon1, 30 min run) shows two interleaved local-network message streams:At workout end the Watch received
4.47via WatchConnectivity and wroteHKQuantity(unit: .mile(), doubleValue: 4.47)→ Apple Health displayed 4.4 mi instead of 2.78 mi.Why
SENDER=PADmust be keptConnection.swiftreadingODOfromSENDER=PADis intentional and correct: it is how a secondary device (phone/Watch) receives live distance from a primary QZ instance (iPad or another phone). Removing that line would break multi-device setups.Fix
Standardise the iPhone→Watch WatchConnectivity channel to always carry km. The Watch does the single km→miles conversion at write time.
src/ios/lockscreen.mm— stop pre-converting in the iPhone; pass raw km:watchkit Extension/WatchWorkoutTracking.swift— convert at the HealthKit write site:With both changes every distance source (iPhone primary via
lockscreen, iPad/multi-device primary viaConnection.swift) arrives at the Watch in km, and the conversion to miles happens once, in the right place.Test plan
distanceCyclingquantity type)🤖 Generated with Claude Code